package com.dms.modules.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dms.common.exception.BusinessException;
import com.dms.modules.product.entity.Product;
import com.dms.modules.product.entity.ProductComment;
import com.dms.modules.product.mapper.ProductCommentMapper;
import com.dms.modules.product.service.ProductReviewService;
import com.dms.modules.product.service.ProductService;
import com.dms.modules.product.service.ProductSkuService;
import com.dms.modules.product.vo.ProductReviewVO;
import com.dms.modules.user.entity.User;
import com.dms.modules.user.service.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class ProductCommentServiceImpl extends ServiceImpl<ProductCommentMapper, ProductComment> implements ProductReviewService {

    @Autowired
    private ProductService productService;
    
    @Autowired
    private ProductSkuService skuService;
    
    @Autowired
    private UserService userService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addReview(Long userId, Long productId, String content, Integer rating) {
        // 检查是否已评价
        if (hasReviewed(userId, null, productId)) {
            throw new BusinessException("该商品已评价");
        }
        
        // 创建评价
        ProductComment review = new ProductComment();
        review.setUserId(userId);
        review.setProductId(productId);
        review.setRating(rating);
        review.setContent(content);
        review.setStatus(1); // 1-通过
        review.setIsReplied(0); // 0-未回复
        review.setLikeCount(0);
        
        return save(review);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean replyReview(Long reviewId, String reply) {
        if (!StringUtils.hasText(reply)) {
            throw new BusinessException("回复内容不能为空");
        }
        
        ProductComment review = getById(reviewId);
        if (review == null) {
            throw new BusinessException("评价不存在");
        }
        
        review.setReply(reply);
        review.setIsReplied(1);
        return updateById(review);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteReview(Long userId, Long reviewId) {
        ProductComment review = getById(reviewId);
        if (review == null) {
            throw new BusinessException("评价不存在");
        }
        
        if (!review.getUserId().equals(userId)) {
            throw new BusinessException("无权删除该评价");
        }
        
        // 软删除
        review.setStatus(2); // 2-拒绝（视为删除）
        return updateById(review);
    }

    @Override
    public IPage<ProductReviewVO> getProductReviews(Long productId, Integer pageNum, Integer pageSize) {
        Page<ProductComment> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<ProductComment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductComment::getProductId, productId)
                .eq(ProductComment::getStatus, 1) // 1-通过
                .orderByDesc(ProductComment::getCreateTime);
        
        IPage<ProductComment> reviewPage = page(page, wrapper);
        return reviewPage.convert(this::convertToVO);
    }

    @Override
    public IPage<ProductReviewVO> getUserReviews(Long userId, Integer pageNum, Integer pageSize) {
        Page<ProductComment> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<ProductComment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductComment::getUserId, userId)
                .eq(ProductComment::getStatus, 1) // 1-通过
                .orderByDesc(ProductComment::getCreateTime);
        
        IPage<ProductComment> reviewPage = page(page, wrapper);
        return reviewPage.convert(this::convertToVO);
    }

    @Override
    public List<Integer> getProductRatings(Long productId) {
        LambdaQueryWrapper<ProductComment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductComment::getProductId, productId)
                .eq(ProductComment::getStatus, 1) // 1-通过
                .select(ProductComment::getRating);
        
        List<ProductComment> reviews = list(wrapper);
        List<Integer> ratings = new ArrayList<>(5);
        for (int i = 1; i <= 5; i++) {
            final int rating = i;
            long count = reviews.stream().filter(r -> r.getRating().equals(rating)).count();
            ratings.add((int) count);
        }
        return ratings;
    }

    @Override
    public Integer getReviewCount(Long productId) {
        LambdaQueryWrapper<ProductComment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductComment::getProductId, productId)
                .eq(ProductComment::getStatus, 1); // 1-通过
        return count(wrapper);
    }

    @Override
    public Double getAverageRating(Long productId) {
        LambdaQueryWrapper<ProductComment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductComment::getProductId, productId)
                .eq(ProductComment::getStatus, 1) // 1-通过
                .select(ProductComment::getRating);
        
        List<ProductComment> reviews = list(wrapper);
        if (reviews.isEmpty()) {
            return 0.0;
        }
        
        double sum = reviews.stream().mapToInt(ProductComment::getRating).sum();
        return sum / reviews.size();
    }

    @Override
    public boolean hasReviewed(Long userId, Long orderId, Long productId) {
        LambdaQueryWrapper<ProductComment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductComment::getUserId, userId)
                .eq(ProductComment::getProductId, productId);
        
        if (orderId != null) {
            wrapper.eq(ProductComment::getOrderId, orderId);
        }
        
        return count(wrapper) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean likeReview(Long userId, Long reviewId) {
        ProductComment review = getById(reviewId);
        if (review == null) {
            throw new BusinessException("评价不存在");
        }
        
        review.setLikeCount(review.getLikeCount() + 1);
        return updateById(review);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean unlikeReview(Long userId, Long reviewId) {
        ProductComment review = getById(reviewId);
        if (review == null) {
            throw new BusinessException("评价不存在");
        }
        
        if (review.getLikeCount() > 0) {
            review.setLikeCount(review.getLikeCount() - 1);
            return updateById(review);
        }
        return true;
    }

    @Override
    public Map<String, Object> getReviewStats(Long productId) {
        LambdaQueryWrapper<ProductComment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductComment::getProductId, productId)
                .eq(ProductComment::getStatus, 1); // 1-通过
        
        List<ProductComment> reviews = list(wrapper);
        
        Map<String, Object> stats = new HashMap<>();
        stats.put("total", reviews.size());
        
        // 计算各评分数量
        Map<Integer, Long> ratingCounts = reviews.stream()
                .collect(Collectors.groupingBy(ProductComment::getRating, Collectors.counting()));
        stats.put("ratingCounts", ratingCounts);
        
        // 计算平均评分
        double avgRating = reviews.stream()
                .mapToInt(ProductComment::getRating)
                .average()
                .orElse(0.0);
        stats.put("averageRating", avgRating);
        
        return stats;
    }
    
    /**
     * 转换为VO对象
     */
    private ProductReviewVO convertToVO(ProductComment review) {
        if (review == null) {
            return null;
        }
        
        ProductReviewVO vo = new ProductReviewVO();
        BeanUtils.copyProperties(review, vo);
        
        // 设置用户信息
        User user = userService.getById(review.getUserId());
        if (user != null) {
            vo.setNickname(user.getNickname());
            vo.setAvatar(user.getAvatar());
        }
        
        // 设置商品信息
        Product product = productService.getById(review.getProductId());
        if (product != null) {
            vo.setProductName(product.getName());
            vo.setProductImage(product.getMainImage());
        }
        
        // 转换图片列表
        if (StringUtils.hasText(review.getImages())) {
            vo.setImages(Arrays.asList(review.getImages().split(",")));
        }
        
        return vo;
    }
} 